package com.dixon.worddayday.service;

import com.dixon.worddayday.bo.FailByDayBean;
import com.dixon.worddayday.config.BusinessException;
import com.dixon.worddayday.dao.ProgressRepository;
import com.dixon.worddayday.dao.ProgressSpecification;
import com.dixon.worddayday.dao.ReviewRecordRepository;
import com.dixon.worddayday.dao.WordsTestDetailRepository;
import com.dixon.worddayday.dto.ProgressStatistical;
import com.dixon.worddayday.model.Customer;
import com.dixon.worddayday.model.Progress;
import com.dixon.worddayday.model.Words;
import com.dixon.worddayday.request.ProgressReq;
import com.dixon.worddayday.util.WordFormatUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProgressService {
    @Autowired
    private ProgressRepository progressRepository;
    @Autowired
    private ReviewRecordRepository reviewRecordRepository;

    @Autowired
    private WordsTestDetailRepository wordsTestDetailRepository;

    public Page<Progress> getMyProgress(Customer customer, ProgressReq progressReq) {

        Pageable pageable = PageRequest.of(1-1, 20, Sort.by(Sort.Direction.DESC, "createTime"));
        if(progressReq != null) {
            pageable = PageRequest.of(progressReq.getPage()-1, progressReq.getSize(), Sort.by(Sort.Direction.DESC, "createTime"));
        }

        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customer.getId());
        params.put("notEqualStatus", "3");
        return progressRepository.findAll(new ProgressSpecification(params), pageable);
    }

    public Progress detail(Integer progressId) {
        Progress progress = progressRepository.findById(progressId).get();

        Words returnWord = new Words();
        BeanUtils.copyProperties(progress.getWords(), returnWord);
        WordFormatUtil.formatWordExampleSentence(returnWord);
        progress.setWords(returnWord);

        return progress;
    }

    public void delete(Customer customer, Integer progressId) {
        Progress progress = progressRepository.findById(progressId).get();

        if(!progress.getCustomerId().equals(customer.getId())) {
            throw new BusinessException("不能删除非自己的单词");
        }

        progress.setStatus("3");

        progressRepository.save(progress);
        log.info("progress del ,id is {}", progressId);
    }


    public ProgressStatistical statistical(Customer customer) {
        int total = progressRepository.countTotal(customer.getId());
        int complete = progressRepository.countComplete(customer.getId());

        int totalReview = reviewRecordRepository.countTotal(customer.getId());
        int fail = reviewRecordRepository.countFail(customer.getId());

        List<FailByDayBean> failByDayBeans = reviewRecordRepository.countFailByDay(customer.getId());

        return ProgressStatistical.builder()
                .totalWordCount(total)
                .completeCount(complete)
                .totalReviewCount(totalReview)
                .failCount(fail)
                .failCountList(failByDayBeans)
                .build();
    }

    public List<Words> randomWord(Customer customer, int size) {
        List<Words> resultList = new ArrayList<>();

        ProgressReq req = new ProgressReq();
        req.setPage(1);
        req.setSize(100000);

        Page<Progress> myProgress = getMyProgress(customer, req);
        if(myProgress.getTotalElements() < size) {
            throw new BusinessException("单词不足，无法返回抽查");
        }

        List<Progress> list = new ArrayList<>(myProgress.getSize());
        list.addAll(myProgress.getContent());

        Map<String, Integer> totalTestWordsMap = getTotalTestWords(customer);

        list = list.stream().filter(e -> !totalTestWordsMap.containsKey(e.getWords().getWord())).collect(Collectors.toList());

        Collections.shuffle(list);

        for (Progress progress : list) {
            resultList.add(progress.getWords());
            if(resultList.size() == size) {
                break;
            }
        }

        if(resultList.size() < size) {
            throw new BusinessException("单词不足，无法返回抽查");
        }

        return resultList;
    }


    private Map<String, Integer> getTotalTestWords(Customer customer) {
        List<String> todayTestWords = wordsTestDetailRepository.getTodayTestWords(customer.getId(), LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE));

        if(todayTestWords != null && !todayTestWords.isEmpty()) {
            return todayTestWords.stream().collect(Collectors.toMap(x -> x, x -> Integer.valueOf(1)));
        }

        return new HashMap<>(0);
    }
}
